package cn.steel.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.steel.domain.entity.MaterialReportAudit;
import cn.steel.domain.entity.Product;
import cn.steel.domain.entity.ProductCategory;
import cn.steel.domain.entity.User;
import cn.steel.domain.vo.ProductCategoryVo;

import cn.steel.domain.vo.ProductVo;
import cn.steel.mapper.MaterialReportAuditMapper;
import cn.steel.mapper.ProductCategoryMapper;
import cn.steel.mapper.ProductMapper;
import cn.steel.mapper.UserMapper;
import cn.steel.service.ProductService;
import com.github.pagehelper.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class ProductServiceImpl implements ProductService {

    final private ProductMapper productMapper;
    final private ProductCategoryMapper categoryMapper;
    final private MaterialReportAuditMapper auditMapper;
    final private UserMapper userMapper;
    private final RedisTemplate<String, Object> redisTemplate;
    private static final String CATEGORY_CACHE_KEY = "product:categories";
    @Value("${file.save-dir}")
    private String SAVE_DIR;

    @Value("${file.access-prefix}")
    private String ACCESS_PREFIX;
    private static final long MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB

    /**
     * 分页查询商品列表
     *
     * @param search     搜索关键字
     * @param categoryId 分类 ID
     * @param supplierId 供应商 ID
     * @return 分页结果
     */
    @Override
    public Page<ProductVo> getProductsPaginated(String search, String supplierName, Long categoryId, String shippingRegion, Long supplierId, Integer status) {
        // PageHelper.startPage(page, size) 应该在 Controller 中调用，这里直接查询
        Page<Product> page = (Page<Product>) productMapper.findProductsPaginated(search, supplierName, categoryId, shippingRegion, supplierId, status);
        List<ProductVo> productVOs = page.getResult().stream().map(p -> {
            ProductVo vo = new ProductVo();
            BeanUtil.copyProperties(p, vo);
            ProductCategory category = categoryMapper.findCategoryById(p.getCategoryId());
            vo.setCategoryName(category != null ? category.getName() : "未知分类");
            vo.setSupplierName(p.getSupplierName());
            return vo;
        }).collect(Collectors.toList());

        // 将分页信息转移到 productVOs
        Page<ProductVo> resultPage = new Page<>(page.getPageNum(), page.getPageSize());
        resultPage.setTotal(page.getTotal());
        resultPage.addAll(productVOs);
        return resultPage;
    }
    /**
     * 查询所有商品分类
     *
     * @return 分类列表
     */
    @Override
    public List<ProductCategoryVo> getCategories() {
        List<ProductCategoryVo> cachedCategories = (List<ProductCategoryVo>) redisTemplate.opsForValue().get(CATEGORY_CACHE_KEY);
        if (cachedCategories != null) {
            return cachedCategories;
        }

        List<ProductCategory> categories = categoryMapper.findAllCategories();
        List<ProductCategoryVo> categoryVOs = categories.stream()
                .map(c -> BeanUtil.toBean(c, ProductCategoryVo.class))
                .collect(Collectors.toList());
        redisTemplate.opsForValue().set(CATEGORY_CACHE_KEY, categoryVOs, 1, TimeUnit.HOURS);
        return categoryVOs;
    }

    /**
     * 根据 ID 查询商品
     *
     * @param id 商品 ID
     * @return 商品信息
     */
    @Override
    public Product getProductById(Long id) {
        return productMapper.findProductById(id);
    }

    /**
     * 新增商品
     *
     * @param product           商品信息
     * @param materialReportFile 材质报告文件
     * @param imageFile         商品图片文件
     */
    @Override
    @Transactional
    public void addProduct(Product product, MultipartFile materialReportFile, MultipartFile imageFile) {
        User supplier = userMapper.findUserById(product.getSupplierId());
        if (supplier == null) {
            throw new IllegalArgumentException("供应商不存在");
        }
        product.setSupplierName(supplier.getCompany());

        if (materialReportFile == null || materialReportFile.isEmpty()) {
            throw new IllegalArgumentException("材质报告文件为必填项");
        }
//        String reportPath = saveFile(materialReportFile, "material_", ".pdf");
        String reportPath = saveFile(materialReportFile, "material_", ".pdf", product.getName());
        product.setMaterialReportUrl(reportPath);

        if (imageFile != null && !imageFile.isEmpty()) {
            String imagePath = saveFile(imageFile, "image_", ".jpg,.png", product.getName());
            product.setImageUrl(imagePath);
        }

        product.setStatus(0); // 默认下架
        product.setCreateTime(LocalDateTime.now());
        product.setUpdateTime(LocalDateTime.now());
        productMapper.insertProduct(product);

        MaterialReportAudit audit = new MaterialReportAudit();
        audit.setProductId(product.getId());
        audit.setSupplierId(product.getSupplierId());
        audit.setReportUrl(reportPath);
        audit.setStatus("PENDING");
        audit.setCreateTime(LocalDateTime.now());
        auditMapper.insertAudit(audit);
    }
    /**
     * 修改商品
     *
     * @param product           商品信息
     * @param materialReportFile 材质报告文件
     * @param imageFile         商品图片文件
     */
    @Override
    @Transactional
    public void updateProduct(Product product, MultipartFile materialReportFile, MultipartFile imageFile) {
        Product existing = productMapper.findProductById(product.getId());
        if (existing == null) {
            throw new IllegalArgumentException("商品不存在");
        }
        User supplier = userMapper.findUserById(product.getSupplierId());
        if (supplier == null) {
            throw new IllegalArgumentException("供应商不存在");
        }
        product.setSupplierName(supplier.getCompany());

        if (materialReportFile != null && !materialReportFile.isEmpty()) {
            if (existing.getMaterialReportUrl() != null) {
                deleteFile(existing.getMaterialReportUrl());
            }
            String reportPath = saveFile(materialReportFile, "material_", ".pdf", product.getName());
            product.setMaterialReportUrl(reportPath);

            MaterialReportAudit existingAudit = auditMapper.findByProductId(product.getId());
            if (existingAudit != null) {
                existingAudit.setReportUrl(reportPath);
                existingAudit.setStatus("PENDING");
                existingAudit.setAuditComment(null);
                existingAudit.setAuditorId(null);
                existingAudit.setAuditTime(null);
                existingAudit.setCreateTime(LocalDateTime.now());
                auditMapper.updateAudit(existingAudit);
            } else {
                MaterialReportAudit audit = new MaterialReportAudit();
                audit.setProductId(product.getId());
                audit.setSupplierId(product.getSupplierId());
                audit.setReportUrl(reportPath);
                audit.setStatus("PENDING");
                audit.setCreateTime(LocalDateTime.now());
                auditMapper.insertAudit(audit);
            }
        } else {
            product.setMaterialReportUrl(existing.getMaterialReportUrl());
        }

        if (imageFile != null && !imageFile.isEmpty()) {
            if (existing.getImageUrl() != null) {
                deleteFile(existing.getImageUrl());
            }
            String imagePath = saveFile(imageFile, "image_", ".jpg,.png", product.getName());
            product.setImageUrl(imagePath);
        } else {
            product.setImageUrl(existing.getImageUrl());
        }

        product.setStatus(0); // 编辑后下架
        product.setUpdateTime(LocalDateTime.now());
        productMapper.updateProduct(product);
    }

    /**
     * 删除商品
     *
     * @param id 商品 ID
     */
    @Override
    @Transactional
    public void deleteProduct(Long id) {
        Product product = productMapper.findProductById(id);
        if (product != null) {
            if (product.getMaterialReportUrl() != null) {
                deleteFile(product.getMaterialReportUrl());
            }
            if (product.getImageUrl() != null) {
                deleteFile(product.getImageUrl());
            }
            productMapper.deleteProduct(id);
            log.info("Deleted product with id: {}", id);
        } else {
            throw new IllegalArgumentException("商品不存在");
        }
    }
    /**
     * 根据 ID 查询商品分类名称
     *
     * @param categoryId 商品分类 ID
     * @return 商品分类名称
     */
    @Override
    public String findCategoryById(Long categoryId) {
        if (categoryId == null) {
            return null;
        }
        ProductCategory category = categoryMapper.findCategoryById(categoryId);
        if (category != null) {
            return category.getName();
        }
        return null;
    }
    /**
     * 上传文件
     *
     * @param file 文件
     * @return 文件路径
     */
    private String uploadFile(MultipartFile file) {
        // 实现文件上传逻辑，例如保存到本地或云存储，返回文件 URL
        // 示例：保存到本地并返回相对路径
        String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
        File dest = new File(SAVE_DIR + fileName);
        try {
            file.transferTo(dest);
            return "/uploads/" + fileName;
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败", e);
        }
    }
    /**
     * 保存文件
     *
     * @param file 文件
     * @param prefix 文件名前缀
     * @param allowedExtensions 允许的文件扩展名
     * @return 相对访问路径
     */
    private String saveFile(MultipartFile file, String prefix, String allowedExtensions, String productName) {
        if (file.getSize() > MAX_FILE_SIZE) {
            throw new IllegalArgumentException("文件大小超过限制（10MB）");
        }
        String originalFilename = file.getOriginalFilename();
        String extension = originalFilename != null ? originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase() : "";
        if (!allowedExtensions.contains(extension)) {
            throw new IllegalArgumentException("不支持的文件类型，仅允许: " + allowedExtensions);
        }
        // 使用商品名称并加上时间戳以避免重名
        String sanitizedProductName = productName.replaceAll("[^a-zA-Z0-9]", "_"); // 清理文件名中的非法字符
        String uniqueFileName = prefix + sanitizedProductName + "_" + System.currentTimeMillis() + extension;
//        String uniqueFileName = prefix + UUID.randomUUID() + extension;

        File dest = new File(SAVE_DIR + uniqueFileName);
        if (!dest.getParentFile().exists()) {
            boolean created = dest.getParentFile().mkdirs();
            if (!created) {
                throw new RuntimeException("无法创建保存目录: " + dest.getParentFile().getAbsolutePath());
            }
        }
        try {
            file.transferTo(dest);
            log.info("文件保存成功: {}", dest.getAbsolutePath());
        } catch (IOException e) {
            throw new RuntimeException("文件保存失败: " + e.getMessage(), e);
        }
        return ACCESS_PREFIX + uniqueFileName; // 返回给前端访问用的路径
    }

    /**
     * 删除文件
     *
     * @param filePath 文件访问路径，比如 /save/xxx.pdf
     */
    private void deleteFile(String filePath) {
        File file = new File(SAVE_DIR + filePath.substring(ACCESS_PREFIX.length()));
        if (file.exists() && file.delete()) {
            log.info("Deleted file: {}", file.getPath());
        } else {
            log.warn("Failed to delete file: {}", file.getPath());
        }
    }

    /**
     * 批量导入商品
     *
     * @param products 商品列表
     * @param supplierId 供应商 ID
     */
    @Override
    @Transactional
    public void batchImportProducts(List<Product> products, Long supplierId) {
        User supplier = userMapper.findUserById(supplierId);
        if (supplier == null) {
            throw new IllegalArgumentException("供应商不存在");
        }
        for (Product product : products) {
            product.setSupplierId(supplierId);
            product.setSupplierName(supplier.getCompany());
            product.setMaterialReportUrl(null); // 允许为空，后期通过编辑补充
            product.setImageUrl(null); // 允许为空，后期通过编辑补充
            product.setStatus(0); // 默认下架
            product.setCreateTime(LocalDateTime.now());
            product.setUpdateTime(LocalDateTime.now());
            productMapper.insertProduct(product);
        }
    }

    /**
     * 获取商品列表用于导出
     *
     * @param search 搜索条件
     * @param categoryId 分类 ID
     * @param status 商品状态
     * @param supplierId 供应商 ID
     * @return 商品列表
     */
    @Override
    public List<Product> getProductsForExport(String search, Long categoryId, Integer status, Long supplierId) {
        return productMapper.findProductsPaginated(search, null, categoryId, null, supplierId, status);
    }
}